package com.onlyphoto.onlymall.base

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.IdRes
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import com.onlyphoto.onlymall.interfaces.RetryCallback
import com.onlyphoto.onlymall.R
import com.onlyphoto.onlymall.events.LoginInvalidEvent
import com.onlyphoto.onlymall.mvp.view.activity.LoginActivity
import com.onlyphoto.onlymall.utils.ConfigUtil
import com.onlyphoto.onlymall.utils.LogUtil
import com.onlyphoto.onlymall.utils.SchemeTool
import com.onlyphoto.onlymall.utils.UserUtil
import com.onlyphoto.onlymall.widget.CommonStatusView
import com.onlyphoto.onlymall.widget.DefaultLoadingDialog
import com.trello.rxlifecycle4.components.support.RxAppCompatActivity
import me.bakumon.statuslayoutmanager.library.StatusLayoutManager
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import qiu.niorgai.StatusBarCompat

/**
 * Created by gaochujia on 2019-06-27.
 */
abstract class BaseActivity<T : BasePresenter<*, *>> : RxAppCompatActivity(), RetryCallback {
    var defaultPostLoadingDialog: DefaultLoadingDialog? = null
    lateinit var mContext: Context
    var mPresenter: T? = null
    var statusLayoutManager: StatusLayoutManager? = null
    protected var builder: StatusLayoutManager.Builder? = null
    var commonStatusView: CommonStatusView? = null

    internal var isActive = true
    @Volatile protected var shouldShow = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)
        setContentView(setContentViewId())
        commonStatusView = CommonStatusView(this)
        defaultPostLoadingDialog = DefaultLoadingDialog()
        defaultPostLoadingDialog!!.isCancelable = false
        mContext = this
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(mContext, R.color.white))
            this.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        }

        if (isFullScreen()) {
            setStatusBar()
        }
        createPresenter()
        initCustomerStatusManager()
        init()
        initListener()
        loadData()

    }

    /**
     * 获取contentView 资源id
     */
    abstract fun setContentViewId(): Int

    /**
     * 初始化
     */
    abstract fun init()

    /**
     * views初始化完成
     */
    abstract fun initListener()

    /**
     * 加载数据
     */
    abstract fun loadData()

    /**
     * 是否沉浸式
     *
     * @return true 全屏模式; false 普通
     */
    abstract fun isFullScreen(): Boolean

    /**
     * 初始化statusBar状态栏 包括颜色、透明度，子类可以覆写该方法
     * 这边采用StatusBaeCompat解决方案
     * 具体可以参照：@Link https://github.com/niorgai/StatusBarCompat
     */
    open fun setStatusBar() {
        StatusBarCompat.translucentStatusBar(this, true)
    }

    /**
     * initCustomerStatusManager 在此初始化页面自定义StatusManager 中的Builder
     */
    protected abstract fun initCustomerStatusManager()

    private fun getContentView(): View {
        return (this.findViewById<View>(android.R.id.content) as ViewGroup).getChildAt(0)
    }

    protected fun Activity.showToast(message: String, length: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, message, length).show()
    }

    /**
     * 创建presenter实例
     */
    abstract fun createPresenter()

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        mPresenter?.onDestroy()//页面销毁 网络请求同销毁
        if (null != defaultPostLoadingDialog!!.dialog && defaultPostLoadingDialog!!.dialog!!.isShowing) {
            defaultPostLoadingDialog!!.dismissAllowingStateLoss()
        }
        //myHandler?.removeCallbacksAndMessages(null)
    }

    fun showDefaultDialog() {
        if (null != defaultPostLoadingDialog!!.dialog && defaultPostLoadingDialog!!.dialog!!.isShowing) {
            return
        }
        defaultPostLoadingDialog?.show(supportFragmentManager, "loading", true)
    }

    fun hideDefaultDialog() {
        if (null != defaultPostLoadingDialog) {
            if (null != defaultPostLoadingDialog!!.dialog && defaultPostLoadingDialog!!.dialog!!.isShowing) {
                defaultPostLoadingDialog!!.dismissAllowingStateLoss()
            }
        }
    }

    protected fun showCustomLayout(customLayout: View, @IdRes vararg clickViewID: Int) {
        if (null == statusLayoutManager) {
            throw RuntimeException("you may forget init StatusLayoutManager first?")
        }
        if (null != statusLayoutManager && null != defaultPostLoadingDialog) {
            if (null != defaultPostLoadingDialog!!.dialog && defaultPostLoadingDialog!!.dialog!!.isShowing) {
                defaultPostLoadingDialog!!.dismissAllowingStateLoss()
            }
            statusLayoutManager!!.showCustomLayout(customLayout, *clickViewID)
        }
    }

    override fun onPause() {
        super.onPause()
        if (null != defaultPostLoadingDialog!!.dialog && defaultPostLoadingDialog!!.dialog!!.isShowing) {
            defaultPostLoadingDialog!!.dismissAllowingStateLoss()
        }
    }

    override fun onResume() {
        super.onResume()
        doJump()
    }


    private fun doJump() {
        SchemeTool.isNeedJump(this)
    }

    protected fun showSuccess() {
        if (null == statusLayoutManager) {
            throw RuntimeException("you may forget init StatusLayoutManager first?")
        }
        if (null != statusLayoutManager && null != defaultPostLoadingDialog) {
            if (null != defaultPostLoadingDialog!!.getDialog() && defaultPostLoadingDialog!!.dialog!!.isShowing) {
                defaultPostLoadingDialog!!.dismissAllowingStateLoss()
            }
            statusLayoutManager!!.showSuccessLayout()
        }
    }

    fun startActivityWithLogin(cls: Class<*>) {
        val intent = Intent()
        if (!ConfigUtil.instance.loginStatus) {
            intent.setClass(this, LoginActivity::class.java)
            intent.putExtra("url", cls.name)
            startActivity(intent)
        } else {
            intent.setClass(this, cls)
            startActivity(intent)
        }
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: LoginInvalidEvent) {
        doWhenLoginInvalid()
        LogUtil.log("base", "退出登录了")
    }


    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    open fun doWhenLoginInvalid() {
        UserUtil.logout(this)
        val intent = Intent()
        intent.setClass(this, LoginActivity::class.java)
        startActivity(intent)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            if (isShouldHideInput(v, ev)) {
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(v?.windowToken, 0)
                v?.clearFocus()
            }
            return super.dispatchTouchEvent(ev)
        }
        //必不可少，否则所有的组件都不会有TouchEvent了
        return if (window.superDispatchTouchEvent(ev)) {
            true
        } else onTouchEvent(ev)
    }

    //点击编辑框以外区域则隐藏键盘
    private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val leftTop = intArrayOf(0, 0)
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + v.height
            val right = left + v.width
            return !(event.x > left && event.x < right
                    && event.y > top && event.y < bottom)
        }
        return false
    }
}

